package com.yangxu.hospital.system.modules.system.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yangxu.hospital.logging.annotation.Log;
import com.yangxu.hospital.system.modules.system.domain.AppointmentSlots;
import com.yangxu.hospital.system.modules.system.domain.DoctorSchedule;
import com.yangxu.hospital.system.modules.system.domain.SysDoctor;
import com.yangxu.hospital.system.modules.system.domain.dto.DoctorScheduleDto;
import com.yangxu.hospital.system.modules.system.domain.vo.DoctorScheduleQueryCriteria;
import com.yangxu.hospital.system.modules.system.service.AppointmentSlotsService;
import com.yangxu.hospital.system.modules.system.service.DoctorScheduleService;
import com.yangxu.hospital.system.modules.system.service.SysDoctorService;
import com.yangxu.hospital.tools.utils.TimeUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import net.dreamlu.mica.core.result.R;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.yangxu.hospital.common.utils.PageResult;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author 杨旭
* @date 2024-11-25
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "doctor_schedule管理")
@RequestMapping("/api/doctorSchedule")
public class DoctorScheduleController {

    private final DoctorScheduleService doctorScheduleService;
    private final SysDoctorService sysDoctorService;
    private final AppointmentSlotsService appointmentSlotsService;


    @Log("导出数据")
    @ApiOperation("导出数据")
    @GetMapping(value = "/download")
    @PreAuthorize("@el.check('doctorSchedule:list')")
    public void exportDoctorSchedule(HttpServletResponse response, DoctorScheduleQueryCriteria criteria) throws IOException {
        doctorScheduleService.download(doctorScheduleService.queryAll(criteria), response);
    }

    @GetMapping
    @Log("查询doctor_schedule")
    @ApiOperation("查询doctor_schedule")
    @PreAuthorize("@el.check('doctorSchedule:list')")
    public ResponseEntity<PageResult<DoctorSchedule>> queryDoctorSchedule(DoctorScheduleQueryCriteria criteria, Page<Object> page){
        return new ResponseEntity<>(doctorScheduleService.queryAll(criteria,page), HttpStatus.OK);
    }

    @PostMapping
    @Log("新增doctor_schedule")
    @ApiOperation("新增doctor_schedule")
    @PreAuthorize("@el.check('doctorSchedule:add')")
    public ResponseEntity<Object> createDoctorSchedule(@Validated @RequestBody Map<String, Object> param){
        List<String> days = new ArrayList<>();
        for (String s : (List<String>) param.get("scheduleDate")) {
            List<String> weekdaysInCurrentMonth = TimeUtils.getWeekdaysInNext30Days(s);
            days.addAll(weekdaysInCurrentMonth);
        }
        param.put("scheduleDate",days);
        return doctorScheduleService.addDoctorSchedule(param);
    }

    @GetMapping("/getCurrentAll")
    @Log("获取当前月的所有排班信息")
    @ApiOperation("获取当前月的所有排班信息")
    @PreAuthorize("@el.check('doctorSchedule:list')")
    public ResponseEntity<List<DoctorScheduleDto>> getCurrentAll(DoctorScheduleQueryCriteria criteria ){
        return new ResponseEntity<>(doctorScheduleService.getCurrentAll(criteria), HttpStatus.OK);
    }


    @PutMapping
    @Log("修改doctor_schedule")
    @ApiOperation("修改doctor_schedule")
    @PreAuthorize("@el.check('doctorSchedule:edit')")
    public ResponseEntity<Object> updateDoctorSchedule(@Validated @RequestBody DoctorSchedule resources){
        doctorScheduleService.update(resources);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @DeleteMapping
    @Log("删除doctor_schedule")
    @ApiOperation("删除doctor_schedule")
    @PreAuthorize("@el.check('doctorSchedule:del')")
    @Transactional
    public ResponseEntity<Object> deleteDoctorSchedule(@RequestBody List<Long> ids) {
        // 获取所有要删除的医生日程安排
        List<DoctorSchedule> doctorSchedules = doctorScheduleService.listByIds(ids);

        // 构建需要删除的排号记录的条件
        Set<Long> doctorIds = doctorSchedules.stream()
                .map(DoctorSchedule::getDoctorId)
                .collect(Collectors.toSet());

        Set<LocalDate> scheduleDates = doctorSchedules.stream()
                .map(DoctorSchedule::getScheduleDate)
                .collect(Collectors.toSet());

        // 查询相关的医生信息
        LambdaQueryWrapper<SysDoctor> sysDoctorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysDoctorLambdaQueryWrapper.in(SysDoctor::getDoctorId, doctorIds);
        List<SysDoctor> doctors = sysDoctorService.list(sysDoctorLambdaQueryWrapper);

        // 构建需要删除的排号记录的部门ID映射
        Map<Long, Long> doctorToDepartmentMap = doctors.stream()
                .collect(Collectors.toMap(SysDoctor::getDoctorId, SysDoctor::getDepartmentId));

        // 构建需要删除的排号记录的条件
        LambdaQueryWrapper<AppointmentSlots> appointmentSlotsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appointmentSlotsLambdaQueryWrapper.in(AppointmentSlots::getDoctorId, doctorIds);
        appointmentSlotsLambdaQueryWrapper.in(AppointmentSlots::getScheduleDate, scheduleDates);
        appointmentSlotsLambdaQueryWrapper.in(AppointmentSlots::getDepartmentId, doctorToDepartmentMap.values());

        // 执行批量删除排号记录
        appointmentSlotsService.remove(appointmentSlotsLambdaQueryWrapper);

        // 删除医生日程安排
        doctorScheduleService.deleteAll(ids);

        return new ResponseEntity<>(HttpStatus.OK);
    }
}